#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>

class Component;
class Mediator
{
public:
    virtual void notify(Component* sender, std::string event) = 0;
};

class Component
{
protected:
    Mediator* dialog = nullptr;
    std::string name;
public:
    Component(Mediator *dialog_, std::string name_)
    {
        dialog = dialog_;
        name = name_;
    }
    std::string getName()
    {
        return name;
    }
    virtual void click() = 0;
    virtual void keypress() = 0;
};

class Button : public Component
{
public:
    Button(Mediator *dialog, std::string name) : Component(dialog, name) {
    }
    void click() override
    {
        dialog->notify(this, "click");
    }
    void keypress() override
    {
        dialog->notify(this, "keypress");
    }
};

class Textbox : public Component
{
public:
    Textbox(Mediator *dialog, std::string name) : Component(dialog, name) {
    }
    void click() override
    {
        dialog->notify(this, "click");
    }
    void keypress() override
    {
        dialog->notify(this, "keypress");
    }
};

class Checkbox : public Component
{
public:
    Checkbox(Mediator *dialog, std::string name) : Component(dialog, name) {
    }
    void click() override
    {
        dialog->notify(this, "click");
    }
    void keypress() override
    {
        dialog->notify(this, "keypress");
    }
};

class AuthenticationDialog: public Mediator
{
private:
    std::string title;
    Button *pBtn1 = nullptr;
    Button *pBtn2 = nullptr;
    Textbox* ptext1 = nullptr;
    Textbox* ptext2 = nullptr;

public:
    AuthenticationDialog()
    {
        pBtn1  = new Button(this,  "Button1");
        pBtn2  = new Button(this,  "Button2");
        ptext1 = new Textbox(this, "Textbox1");
        ptext2 = new Textbox(this, "Textbox2");
    }
    void notify(Component* sender, std::string event) override
    {
        std::cout<<sender->getName()<<"  "<<event<<std::endl;
    }
    void login()
    {
        notify(ptext1, "keypress");
        notify(pBtn1, "click");
    }
};

int main() {
    AuthenticationDialog authenticationDialog;
    authenticationDialog.login();
    return 0;
}